----------------------------------
--      Module Declaration      --
----------------------------------

local mod = BigWigs:New("Flash", "$Revision: 5566 $")
if not mod then return end

--------------------------------------------------------------------------------
-- Locals
--

-- Frames
local flasher = nil
local shaker = nil

-- Shake properties
local shaking = nil
local SHAKE_DURATION = 0.8
local SHAKE_X = 10
local SHAKE_Y = 10
local fail = nil

----------------------------
--      Localization      --
----------------------------

local L = AceLibrary("AceLocale-2.2"):new("BigWigsFlashNShake")
L:RegisterTranslations("enUS", function() return {
	["FlashNShake"] = true,
	["Flash'N'Shake"] = true,
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = true,

	["Flash"] = true,
	["Toggle Flash on or off."] = true,

	["Shake"] = true,
	["Toggle Shake on or off."] = true,

	["Test"] = true,
	["Perform a Flash/Shake test."] = true,

	flash_warning = "Screen shaking failed. This is usually caused by nameplates.\nTurn off nameplates and reload your UI, or turn off the shake effect in Big Wigs.",
} end)

L:RegisterTranslations("koKR", function() return {
	["FlashNShake"] = "깜박임과 진동",
	["Flash'N'Shake"] = "깜박임과 진동",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "당신에게 직접적으로 중요한 무언가가 영향을 미칠때 화면을 흔들거나 파란색으로 깜박입니다.",

	["Flash"] = "깜박임",
	["Toggle Flash on or off."] = "깜박임을 켜거나 끕니다.",

	["Shake"] = "진동",
	["Toggle Shake on or off."] = "진동을 켜거나 끕니다.",

	["Test"] = "테스트",
	["Perform a Flash/Shake test."] = "깜박임/진동 테스트를 실행합니다.",

	flash_warning = "화면 진동이 실패했습니다. 이것은 보통 nameplates(이름표 표시)가 켜져 있을 때 일어납니다.\n nameplates(이름표 표시)를 끄고 UI를 다시 로딩을 하거나 BigWigs의 '진동'을 끄세요. (깜박임은 영향 받지 않습니다)",
} end)

L:RegisterTranslations("frFR", function() return {
	["Flash'N'Shake"] = "Flash'N'Shake",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "Secoue et/ou fait clignoter l'écran en bleu quand quelque chose d'important vous affecte directement.",

	["Flash"] = "Flash",
	["Toggle Flash on or off."] = "Fait clignoter ou non l'écran.",

	["Shake"] = "Secousse",
	["Toggle Shake on or off."] = "Secoue ou non l'écran.",

	["Test"] = "Test",
	["Perform a Flash/Shake test."] = "Effectue un test du flash/de la secousse.",

	flash_warning = "Échec de la secousse de l'écran. Ceci arrive habituellement quand les \"nameplates\" (l'affichage des noms et des barres de vie au dessus des personnages dans le champ du jeu) sont activés.\nDésactivez-les et rechargez l'IU, ou désactivez la 'Secousse' de BigWigs (le flash n'est PAS affecté).",
} end)

L:RegisterTranslations("zhCN", function() return {
	["FlashNShake"] = "屏幕闪烁/震动",
	["Flash'N'Shake"] = "屏幕闪烁/震动",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "如有重要事件发生，屏幕将会蓝色闪烁/震动告知玩家。",

	["Flash"] = "闪烁",
	["Toggle Flash on or off."] = "打开或关闭屏幕闪烁。",

	["Shake"] = "震动",
	["Toggle Shake on or off."] = "打开或关闭屏幕震动。",

	["Test"] = "测试",
	["Perform a Flash/Shake test."] = "屏幕闪烁/震动测试。",

	flash_warning = "屏幕震动失效。\n关闭姓名栏并重置用户界面或关闭 BigWigs“震动”模块。",
} end)

L:RegisterTranslations("zhTW", function() return {
	["FlashNShake"] = "螢幕閃爍/震動",
	["Flash'N'Shake"] = "螢幕閃爍/震動",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "如有重要事件發生，螢幕將會閃爍藍光/震動告知玩家。",

	["Flash"] = "閃爍",
	["Toggle Flash on or off."] = "打開或關閉螢幕閃爍。",

	["Shake"] = "震動",
	["Toggle Shake on or off."] = "打開或關閉螢幕震動。",

	["Test"] = "測試",
	["Perform a Flash/Shake test."] = "測試螢幕閃爍/震動。",

	flash_warning = "螢幕震動失效。\n關閉姓名欄並重置用戶介面或關閉 BigWigs“震動”模組。",
} end)

L:RegisterTranslations("deDE", function() return {
	["FlashNShake"] = "Aufblitzen/Beben",
	["Flash'N'Shake"] = "Aufblitzen & Beben",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "Lässt den Bildschirm beben und/oder blau aufblitzen, wenn etwas Wichtiges passiert, das dich direkt betrifft.",

	["Flash"] = "Aufblitzen",
	["Toggle Flash on or off."] = "Schaltet Aufblitzen ein oder aus.",

	["Shake"] = "Beben",
	["Toggle Shake on or off."] = "Schaltet Beben ein oder aus.",

	["Test"] = "Test",
	["Perform a Flash/Shake test."] = "Führe einen Test von Aufblitzen/Beben durch.",

	flash_warning = "Bildschirmbeben fehlgeschlagen. Dies passiert, wenn die Gesundheitsanzeige unter den Namen eingeschaltet ist.\nSchalte diese aus und lade deine UI neu oder schalte das Beben von Big Wigs aus.",
} end)

L:RegisterTranslations("esES", function() return {
	["FlashNShake"] = "Destello/Temblor",
	["Flash'N'Shake"] = "Destello / Temblor",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "Hacer temblar la pantalla y/o emitir un destello cuando ocurre algo importante que te afecta.",

	["Flash"] = "Destello",
	["Toggle Flash on or off."] = "Activar / Desactivar el destello.",

	["Shake"] = "Temblor",
	["Toggle Shake on or off."] = "Activar / Desactivar el temblor.",

	["Test"] = "Probar",
	["Perform a Flash/Shake test."] = "Efectua una prueba de Destello/Temblor.",

	flash_warning = "Temblor de pantalla fallido. Suele ocurrir cuando las placas de nombre están activadas.\nDesactiva las placas de nombre y reinicia la interfaz o desactiva la función 'Temblor' de BigWigs. (la función de Destello NO se ve afectada)",
} end)

-- Translated by wow.playhard.ru translators
L:RegisterTranslations("ruRU", function() return {
	["FlashNShake"] = "Мерцание и Сотрясение",
	["Flash'N'Shake"] = "Мерцание и Сотрясение",
	["Shake and/or Flash the screen blue when something important happens that directly affects you."] = "Сотрясение и/или мерцание экрана синим цветом, когда происходит нечто важное, что непосредственно влияет или связано с вами.",

	["Flash"] = "Мерцание",
	["Toggle Flash on or off."] = "Вкл/Выкл мерцание экрана.",

	["Shake"] = "Сотрясение",
	["Toggle Shake on or off."] = "Вкл/Выкл сотрясение экрана.",

	["Test"] = "Тест",
	["Perform a Flash/Shake test."] = "Тест Мерцание/Сотрясение.",

	flash_warning = "Неудалась выполнить сотрясение экрана. Это обычно бывает когда таблицы с именами включены.\nВыключите таблицы с именами и перезагрузите ваш UI или отключите эффект 'Сотрясение'.",
} end)

--------------------------------------------------------------------------------
-- Options
--

mod.defaultDB = {
	flash = true,
	shake = false,
}
mod.external = true
mod.consoleCmd = L["FlashNShake"]
mod.consoleOptions = {
	type = "group",
	name = L["Flash'N'Shake"],
	desc = L["Shake and/or Flash the screen blue when something important happens that directly affects you."],
	args = {
		[L["Flash"]] = {
			type = "toggle",
			name = L["Flash"],
			desc = L["Toggle Flash on or off."],
			order = 1,
			get = function() return mod.db.profile.flash end,
			set = function(v)
				mod.db.profile.flash = v
			end,
		},
		[L["Shake"]] = {
			type = "toggle",
			name = L["Shake"],
			desc = L["Toggle Shake on or off."],
			order = 2,
			get = function() return mod.db.profile.shake end,
			set = function(v)
				mod.db.profile.shake = v
			end,
		},
		spacer = {
			type = "header",
			name = " ",
			order = 3,
		},
		[L["Test"]] = {
			type = "execute",
			name = L["Test"],
			desc = L["Perform a Flash/Shake test."],
			order = 4,
			handler = mod,
			func = "BigWigs_Test",
		},
	}
}

------------------------------
--      Initialization      --
------------------------------

function mod:OnEnable()
	self:RegisterEvent("BigWigs_Message")
end

------------------------------
--      Shaking             --
------------------------------

local originalPoints = nil
local function startShake()
	if not shaking then
		-- store old worldframe positions, we need them all, people have frame modifiers for it etc.
		if not originalPoints then
			originalPoints = {}
			for i = 1, WorldFrame:GetNumPoints() do
				table.insert(originalPoints, {WorldFrame:GetPoint(i)})
			end
		end
		shaking = SHAKE_DURATION -- don't think we want to make this a setting.
		shaker:Show()
	end
end

local function shakeOnUpdate(frame, elapsed)
	shaking = shaking - elapsed
	local x, y = 0, 0 -- Resets to original position if we're supposed to stop.
	if shaking <= 0 then -- stop shaking
		shaking = nil
		shaker:Hide()
	else
		x = math.random(-SHAKE_X,SHAKE_X)
		y = math.random(-SHAKE_Y,SHAKE_Y)
	end
	WorldFrame:ClearAllPoints()
	for i, v in ipairs(originalPoints) do
		WorldFrame:SetPoint(v[1], v[2], v[3], v[4] + x, v[5] + y)
	end
end

------------------------------
--      Event Handlers      --
------------------------------

function mod:BigWigs_Message(msg, color)
	if color and color == "Personal" then
		if self.db.profile.flash then
			if not flasher then --frame creation
				flasher = CreateFrame("Frame", "BWFlash", UIParent)
				flasher:SetFrameStrata("BACKGROUND")
				flasher:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",})
				flasher:SetBackdropColor(0,0,1,0.55)
				flasher:SetAllPoints( UIParent)
				flasher:SetScript("OnShow", function (self)
					self.elapsed = 0
					self:SetAlpha(0)
				end)
				flasher:SetScript("OnUpdate", function (self, elapsed)
					elapsed = self.elapsed + elapsed
					if elapsed >= 0.8 then
						self:Hide()
						self:SetAlpha(0)
						return
					end
					local alpha = elapsed % 0.4
					if elapsed > 0.2 then
						alpha = 0.4 - alpha
					end
					self:SetAlpha(alpha * 5)
					self.elapsed = elapsed
				end)
				flasher:Hide()
			end
			flasher:Show()
		end

		if self.db.profile.shake then
			if not shaker then
				shaker = CreateFrame("Frame", "BWShaker", UIParent)
				shaker:Hide()
				shaker:SetScript("OnUpdate", shakeOnUpdate)
			end
			local check = WorldFrame:IsProtected()
			if not check then
				startShake()
			elseif check and not fail then
				BigWigs:Print(L["flash_warning"])
				fail = true
			end
		end
	end
end

function mod:BigWigs_Test()
	self:TriggerEvent("BigWigs_Message", L["Test"], "Personal", true)
end

